﻿namespace AB.ServiceDirectory.Dao
{
    using System;
    using System.Linq;
    using Commons.DataFilters;
    using Entities;

    [Serializable]
    public class AddressLookupDao
    {
        [NonSerialized]
        private readonly ServicesDirectoryDataContext _context = DB.Context;

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="max">The max.</param>
        /// <returns>Address list</returns>
        public IQueryable<Address> GetList(AddressFilter filter, string sortType, int startRowIndex, int max)
        {
            var query = from a in _context.Addresses
                        select a;

            if (filter != null)
            {
                query = GetListQuery(query, filter);
            }

            query = GetListSort(query, sortType);

            query = query.Skip(startRowIndex).Take(max);

            return query;
        }

        // Ho tro viec sap xep
        private static IQueryable<Address> GetListSort(IQueryable<Address> query, string sortType)
        {
            var sortDescending = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                string[] values = sortType.Split(' ');
                sortType = values[0];

                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "AddressLine":
                        query = sortDescending
                                   ? query.OrderByDescending(a => a.AddressLine)
                                   : query.OrderBy(a => a.AddressLine);
                        break;

                    case "Postcode":
                        query = sortDescending
                                   ? query.OrderByDescending(a => a.Postcode)
                                   : query.OrderBy(a => a.Postcode);
                        break;

                    case "TownName":
                        query = sortDescending
                                   ? query.OrderByDescending(a => a.Town.TownName)
                                   : query.OrderBy(a => a.Town.TownName);
                        break;

                    case "CountyName":
                        query = sortDescending
                                   ? query.OrderByDescending(a => a.Town.County.CountyName)
                                   : query.OrderBy(a => a.Town.County.CountyName);
                        break;

                    case "CountryName":
                        query = sortDescending
                                   ? query.OrderByDescending(a => a.Town.County.Country.CountryName)
                                   : query.OrderBy(a => a.Town.County.Country.CountryName);
                        break;
                    default:
                        query = sortDescending
                                   ? query.OrderByDescending(a => a.AddressId)
                                   : query.OrderBy(a => a.AddressId);
                        break;
                }
            }

            return query;
        }

        /// <summary>
        /// Gets the list query.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        private static IQueryable<Address> GetListQuery(IQueryable<Address> data, AddressFilter filter)
        {
            // Filter by Postcode
            if (!string.IsNullOrEmpty(filter.Postcode))
            {
                data = data.Where(a => a.Postcode.StartsWith(filter.Postcode));
            }

            // Filter by street
            if (!string.IsNullOrEmpty(filter.Street))
            {
                data = data.Where(a => a.AddressLine.Contains(filter.Street));
            }

            // Filter by town
            if (!string.IsNullOrEmpty(filter.Town))
            {
                data = data.Where(a => a.Town.TownName.StartsWith(filter.Town));
            }

            return data;
        }

        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public int GetListCount(AddressFilter filter)
        {
            var data = from a in _context.Addresses
                       select a;

            return GetListQuery(data, filter).Count();
        }

        /// <summary>
        /// Gets the gov office region by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>GovOfficeRegion object</returns>
        public Address GetAddressById(int id)
        {
            var objAddress = _context.Addresses.FirstOrDefault(a => a.AddressId == id);
            return objAddress;
        }

        /// <summary>
        /// Gets the address.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns>Address object</returns>
        public Address GetAddress(AddressFilter filter)
        {
            var query = from a in _context.Addresses
                        select a;

            if (!string.IsNullOrEmpty(filter.Postcode))
            {
                query = query.Where(a => a.Postcode.Equals(filter.Postcode));
            }

            if (!string.IsNullOrEmpty(filter.AddressLine))
            {
                query = query.Where(a => a.AddressLine.Equals(filter.AddressLine));
            }

            return query.FirstOrDefault();
        }
    }
}